/** 表格渲染公共方法：管理端、业务端通用 */
import {
  collectPluck,
  flatTableData,
  getBaseApi,
  getDic,
  isFunction,
  tableShowRefdata,
  uniqueArr
} from '@admin/utils/index';
import { invokeMethod } from '@admin/api/common.js';
import { getToken } from '@admin/utils/auth';
import TableOperate from '@admin/packages/table-operate/index.js';
import { COLUMN_VISIBLE } from './const';
import { ElTag, ElLink, ElCheckbox, ElCheckboxGroup } from 'element-plus';

/**
 * 根据后端结构生成显示字段
 *
 * @param {any} tableInfo 接口信息
 * @param {any} lockColumnCount 锁定列数量
 * @param {any} callback 配置回调
 * @param {any} sortColumns 需要排序的字段-数组
 * @param {any} gridInfo 表格配置
 * @param {any} tableLinkBtns 表格链接按钮
 * @returns
 */
export function createTableColumn(
  tableInfo,
  lockColumnCount = 0,
  callback = {},
  sortColumns = [],
  gridInfo = {},
  tableLinkBtns = [],
  templateInstance = null
) {
  const tableTagRule = gridInfo.columnStyle || [];
  const enableSubHeader = gridInfo.enableSubHeader || 0;
  const columnNames = gridInfo.columnName || {};

  const {
    enableTableEdit,
    enableEditCols,
    hideColumns = [], // 隐藏列
    humanDisplay = [] // 富列表
  } = templateInstance || {};
  // 组件单列
  function getTableColumn(item, index) {
    const showRef = tableShowRefdata(item.eleType);
    const returnColumn = {
      prop: item.code,
      label: columnNames[item.code] || item.name,
      render: (h, scope) => {
        const property = scope.column.property;
        const rowData = scope.row;
        let data = scope.row[property];
        const oriData = data;
        const REFNAME = `${property}NAME`;
        if (showRef) {
          if (scope.row.REFDATA && scope.row.REFDATA[REFNAME]) {
            data = scope.row.REFDATA[REFNAME];
          }
          // 文件下载特殊处理
          if (item.eleType === FDUI.eleType.File) {
            // 有文件名时才显示
            if (scope.row.REFDATA && scope.row.REFDATA[REFNAME]) {
              // 去除文件后的id，如：4.jpg|866381832801751040=>4.jpg 同时兼容只有4.jpg这种类型
              /**
               * 新版逻辑：解决了用,分割多个文件可能存在的分割错误的问题
               *
               * 1. 多个文件用:分割
               * 2. 文件之间用|分割文件名和id 旧版逻辑：
               * 3. 多个文件用,分割
               * 4. 文件之间用|分割文件名和id
               */
              // 判断是否是新版
              let fileNames = data.split(',');
              if (data.includes(':')) {
                fileNames = data.split(':');
              }
              data = h(
                'span',
                {},
                fileNames
                  .filter(i => {
                    return i.includes('|');
                  })
                  .map(i => {
                    const [fileName, fileId] = i.split('|');
                    return h(
                      ElLink,
                      {
                        style: 'margin-right:5px',
                        underline: false,
                        type: 'primary',
                        onClick: () => fileClick(fileId, fileName)
                      },
                      { default: () => fileName }
                    );
                  })
              );
            } else {
              data = h('span', {});
            }
          } else if (item.eleType === FDUI.eleType.Image) {
            const props = FDUI.fieldToJson(item, {}, {}, scope.row, {}, tableInfo.fieldList);
            // 图片=>显示为图片
            props.disabled = true;
            return oriData && data
              ? h('img-viewer', {
                key: scope.row.id,
                field: property,
                data: scope.row
              })
              : '';
          }
        }
        // 自定义标签
        const fieldTags = tableTagRule.filter(i => i.column === item.code);
        // 自定义链接
        const matchLinkCols = tableLinkBtns.filter(i => {
          return i.linkColumn === item.code;
        });

        if (fieldTags.length) {
          let type = 'primary';
          let color = '';
          fieldTags.forEach(fieldTag => {
            const { column: field, style: calcRule } = fieldTag;
            const currentRule = (calcRule || []).find(i => {
              const { operator, value } = i;
              if (operator == 3) {
                return scope.row[field] == value;
              } else if (operator == 4) {
                return scope.row[field] != value;
              }
            });
            if (currentRule) {
              type = currentRule.style || '';
              // todo 缺少颜色配置
              color = currentRule.color || '';
            }
          });
          return data ? h(
            ElTag,
            {
              title: data,
              type,
              'disable-transitions': true,
              color
            },
            { default: () => data }
          ) : '';
        } else if (matchLinkCols && matchLinkCols.length) {
          tableLinkBtns = JSON.parse(JSON.stringify(tableLinkBtns));
          const btns = matchLinkCols.map(btn => {
            btn.name = data;
            return btn;
          });
          if (btns && btns.length) {
            return h(TableOperate, {
              btns,
              type: 'text',
              isTableBtn: true,
              gridInfo,
              tableRow: scope.row
            });
          }
          // copy-btn作为复制的必要class，修改时需要注意
          const titleData = ['string', 'number'].includes(typeof data) ? data : '';
          return h(
            'span',
            {
              class: 'copy-btn show-over-tooltip',
              title: titleData
            },
            { default: () => data }
          );
        } else if (humanDisplay.includes(property)) {
          if (item.eleType === FDUI.eleType.Check) {
            // 复选框=>显示为复选框
            return h('span', {}, [
              h(ElCheckbox, {
                value: data,
                'true-label': 1,
                'false-label': 0
              })
            ]);
          } else if (item.eleType === FDUI.eleType.CodeData) {
            // 码表=>显示为复选框
            const codes = getDic(item.codeTypeId) || [];
            const dics = oriData ? oriData.split(',') : [];
            return h('span', {}, [
              h(
                ElCheckboxGroup,
                {
                  value: dics
                },
                {
                  default: () => codes.map(i => {
                    return h(
                      ElCheckbox,
                      {
                        label: i.code
                      },
                      { default: () => i.name }
                    );
                  })
                }
              )
            ]);
          }
        } else if (item.eleDisType === '42' && !(enableEditCols || []).includes(property)) {
          // 年月保存在数字中，需要用-隔开
          if (data) {
            const realData = `${`${data}`.substring(0, 4)}-${`${data}`.substring(4, 6)}`;
            return h(
              'span',
              {
                class: 'copy-btn show-over-tooltip',
                title: realData
              },
              { default: () => realData }
            );
          }
          return h('span', {
            class: 'copy-btn show-over-tooltip'
          }, {});
        } else if (window.$CD && isFunction(window.$CD[callback.columnRender])) {
          return window.$CD[callback.columnRender](scope, data, templateInstance);
        } else {
          if (enableTableEdit) {
            // 有配置子表按钮并且有配置子表保存
            if ((enableEditCols || []).includes(property)) {
              const conf = FDUI.fieldToJson(item);
              return h('field-render', {
                key: scope.row.id,
                conf,
                form: scope.row
              });
            }
            return h(
              'span',
              {
                title: data
              },
              { default: () => data }
            );
          }
          // copy-btn作为复制的必要class，修改时需要注意
          const titleData = ['string', 'number'].includes(typeof data) ? data : '';
          return h(
            'span',
            {
              class: 'copy-btn show-over-tooltip',
              title: titleData
            },
            { default: () => data }
          );
        }
      }
    };
    // 新增锁定列
    if (index < lockColumnCount) {
      // returnColumn['fixed'] = ''
    }
    // 列排序
    if (sortColumns.includes(item.code)) {
      returnColumn.sortable = 'custom';
    }
    return returnColumn;
  }
  let tmpTableColumn = [];
  const fields = tableInfo.fieldList
    .filter(item => {
      return item.accessRight !== COLUMN_VISIBLE.HIDE;
    })
    .filter(item => {
      return !hideColumns.includes(item.code);
    })
    .sort((pre, next) => {
      return pre.orderId >= next.orderId ? 1 : -1;
    })
    .map(i => {
      if (i.groupName === null) {
        i.groupName = '';
      }
      return i;
    });
  // 多级表头
  if (enableSubHeader) {
    let groups = uniqueArr(fields.map(i => i.groupName));
    // 组排序
    groups = groups
      .map(item => {
        const [sort, name] = (item || '').split('.');
        return {
          sort,
          name,
          oriName: item
        };
      })
      .sort((pre, next) => {
        return pre.sort >= next.sort ? 1 : -1;
      });
    return groups.map(group => {
      const children = fields
        .filter(i => {
          return i.groupName === group.oriName;
        })
        .sort((pre, next) => {
          return pre.orderId >= next.orderId ? 1 : -1;
        })
        .map((item, index) => {
          return getTableColumn(item, index);
        });
      console.log(children);
      return {
        label: group.name,
        children
      };
    });
  }
  tmpTableColumn = fields.map((item, index) => {
    return getTableColumn(item, index);
  });

  return tmpTableColumn;
}

// 文件点击
function fileClick(fileId, fileName) {
  const url = `/file/download?id=${fileId}&token=${getToken()}`;
  // 获取后缀名，如果是txt则直接打开。
  const suffix = (fileName || '').match(/[^.]+$/)[0].toLowerCase();
  if (['txt'].includes(suffix)) {
    const baseApi = getBaseApi();
    window.open(baseApi + url);
  } else {
    Vue.prototype.$getDownload(url, fileName);
  }
}

// 生成表格数据
export function createTableData(data) {
  return flatTableData(data);
}
